package com.ltmonitor.jt808.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;

import com.ltmonitor.dao.IBaseIbatisDao;
import com.ltmonitor.entity.Alarm;
import com.ltmonitor.entity.AlarmRecord;
import com.ltmonitor.entity.GPSRealData;
import com.ltmonitor.jt808.service.INewAlarmService;
import com.ltmonitor.jt808.service.ITransferGpsService;
import com.ltmonitor.util.Constants;
import com.ltmonitor.util.DateUtil;
import com.ltmonitor.vo.AlarmMessage;

/**
 * 报警入库服务
 * 
 * @author v5-552
 * 
 */

@Service("newAlarmService")
public class NewAlarmService implements INewAlarmService {

	private static Logger logger = Logger.getLogger(NewAlarmService.class);
	@Autowired
	IBaseIbatisDao baseIbatisDao;

	private ConcurrentLinkedQueue<Alarm> dataQueue = new ConcurrentLinkedQueue<Alarm>();

	private boolean continueProcess = true;

	private Thread processAlarmThread;

	@Autowired
	private ITransferGpsService transferGpsService;

	@Resource(name = "jmsTemplate")
	private JmsTemplate jmsTemplate;

	// 队列名gzframe.demo
	@Resource(name = "queueDestination")
	private Destination queueDestination;

	public void start() {
		processAlarmThread = new Thread(new Runnable() {
			public void run() {
				processRealDataThreadFunc();
			}
		});
		processAlarmThread.start();
	}

	public void stopService() {
		continueProcess = false;
		try {
			processAlarmThread.join(50000);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}
		// processRealDataThread.stop();
	}

	public void enQueue(Alarm newAlarm) {
		if (dataQueue.size() > 2000) {
			logger.error("报警队列中数量过多:" + dataQueue.size());
			this.dataQueue.clear();
		}
		dataQueue.add(newAlarm);
	}

	private void processRealDataThreadFunc() {
		// int count = 0;
		while (continueProcess) {
			try {
				Alarm tm = dataQueue.poll();
				if (tm != null) {
					final List<Alarm> msgList = new ArrayList<Alarm>();
					while (tm != null) {
						msgList.add(tm);
						if (msgList.size() > 100)
							break;
						tm = dataQueue.poll();

					}
					batchInsertAlarm(msgList);
				}
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}

			// count++;
			try {
				Thread.sleep(100L);
			} catch (InterruptedException e1) {
			}
		}
	}

	private void batchInsertAlarm(List<Alarm> alarmList) {
		if (alarmList.size() == 0)
			return;
		String statementName = "jt808server.insertNewAlarm";
		baseIbatisDao.batchInsert(statementName, alarmList);
	}

	private void sendAlarmMessage(final Alarm alarm) {
		logger.error("向队列发送了消息------------");
		
		jmsTemplate.send(this.queueDestination, new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				return session.createObjectMessage(alarm);
			}
		});

	}

	public void insertAlarm(String alarmSource, String alarmType, GPSRealData rd) {
		try {
			Alarm ar = new Alarm();
			ar.setVehicleId(rd.getVehicleId());
			ar.setPlateNo(rd.getPlateNo());
			Date alarmTime = rd.getSendTime();
			if(alarmTime == null || AlarmRecord.TYPE_ONLINE.equals(alarmType) || AlarmRecord.TYPE_OFFLINE.equals(alarmType))
				alarmTime = rd.getOnlineDate();
			ar.setAlarmTime(alarmTime);
			ar.setAckSn(rd.getResponseSn());
			ar.setLatitude(rd.getLatitude());
			ar.setLongitude(rd.getLongitude());
			ar.setSpeed(rd.getVelocity());
			ar.setAlarmType(alarmType);
			ar.setAlarmSource(alarmSource);
			ar.setLocation(rd.getLocation());
			if (AlarmRecord.TYPE_TIRED.equals(ar.getAlarmType())
					&& rd.getTiredAlarmTime() != null) {
				double tiredTime = 4
						* 60
						+ 0.1
						* DateUtil.getSeconds(rd.getTiredAlarmTime(),
								new Date()) / 6;
				String descr = "疲劳驾驶时间："
						+ Constants.getIntervalDescr(tiredTime) + "";
				ar.setDescr(descr);
			}

			String alarmTalbeName = Constants.getAlarmTableName();
			ar.setTableName(alarmTalbeName);
			this.enQueue(ar);
			//this.sendAlarmMessage(ar);
			// this.baseDao.saveOrUpdate(ar);
			// String statementName = "insertNewAlarm";
			// queryDao.insert(statementName, ar);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

}
